package com.threepure.penpipe;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import android.Manifest;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.threepure.penpipe.floatbar.FloatBar;
import com.threepure.penpipe.floatbar.FloatBarListener;
import com.threepure.penpipe.pen.PenConfig;
import com.threepure.penpipe.pen.setting.CircleView;
import com.threepure.penpipe.pen.setting.PenSettingPopupWindow;
import com.threepure.penpipe.setting.SettingPopupWindow;
import com.threepure.penpipe.util.BitmapUtil;
import com.threepure.penpipe.util.Config;
import com.threepure.penpipe.util.DisplayUtil;
import com.threepure.penpipe.util.MyClickListener;
import com.threepure.penpipe.util.ScreenUtils;
import com.threepure.penpipe.util.SystemUtil;
import com.threepure.penpipe.util.colorpicker.ColorPickerDialog;
import com.threepure.penpipe.view.PaintView;

import java.io.File;
import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

@SuppressWarnings("ALL")
public class MainActivity extends AppCompatActivity implements View.OnClickListener, PaintView.StepCallback , MyClickListener.MyClickCallBack {

    private static final String TAG = "TP_MainActivity=> ";

    private final int REQUEST_GPS = 1;

    /**
     * 画布最大宽度
     */
    public static final int CANVAS_MAX_WIDTH  = 3000;

    /**
     * 画布最大高度
     */
    public static final int CANVAS_MAX_HEIGHT = 3000;
    
    /**画板的父容器*/
    private static LinearLayout linearLayout ;

    /**添加一个悬浮菜单*/
    private FloatBar floatBar;
    private ImageView mUndoView;
    private ImageView mRedoView;
    private ImageView mPenView;
    private ImageView mEraserView;
    private ImageView mSaveView;
    private ImageView mSetView;

    /**添加一个设置画笔属性的PopWindow*/
    private PenSettingPopupWindow penSetPopWin;
    /**添加一个设置功能的PopWindow*/
    private SettingPopupWindow settingPopupWindow;

    /**画板对象*/
    private static PaintView mPaintView = null;
    private float mWidth;
    /**通过系统方法获取道德手机高度像素（不包括手机的导航栏状态栏）*/
    private float mHeight;
    /**创建的画布高度（因为设计全面屏以及是否有虚拟导航栏，所以这个画布大小并不一定等于直接获取到的屏幕尺寸）*/
    private float paintHeight;

    //画板的背景颜色
    private int bgColor;
    /**最终的图片是否只截取文字区域*/
    private boolean isCrop = false;
    /**保存文件的格式给PNG还是JPG*/
    private String format;

    /**保存路径*/
    private String mSavePath;

    /**定时器对象*/
    private Timer timer;

    //保存的一个进度条
    private ProgressDialog mSaveProgressDlg;
    private static final int MSG_SAVE_SUCCESS = 1;
    private static final int MSG_SAVE_FAILED  = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        initSystem();

        linearLayout = findViewById(R.id.border_layout);

        //实例化悬浮菜单
        floatBar = new FloatBar(this);
        //根据floatBar初始化各个菜单项目
        initView();
        initData();

        //设置画布默认的背景图片
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.defaultbg);
        bitmap = BitmapUtil.zoomImage(bitmap, (int)mWidth, (int)paintHeight);
        Drawable drawable = new BitmapDrawable(bitmap);
        linearLayout.setBackground(drawable);

        floatBar.setFlowBarListener(new FloatBarListener() {
            @Override
            public void unDoClick() {
                mPaintView.undo();
            }

            @Override
            public void reDoClick() {
                mPaintView.redo();
            }

            @Override
            public void penClick() {
                mEraserView.setSelected(false);
                mPenView.setSelected(true);

                if (mPaintView.isEraser()){
                    mPaintView.setPenType(PaintView.TYPE_PEN);
                }else {
                    penSetPopWin = new PenSettingPopupWindow(MainActivity.this);
                    showPaintSettingWindow();
                    penSetPopWin.showAsDropDown(floatBar);
                }
            }

            @Override
            public void eraserClick() {
                mPenView.setSelected(false);
                mEraserView.setSelected(true);
                mPaintView.setPenType(PaintView.TYPE_ERASER);
            }

            @Override
            public void savaClick() {
                save();
            }

            @Override
            public void setClick() {
                settingPopupWindow = new SettingPopupWindow(MainActivity.this);
                showSettingWindow();
                //将存储起来的橡皮大小设置为这个seekBar的进度。
                settingPopupWindow.setSeekBarProgress(Config.eraserSize);
                //将当前定时器打开状态与否设置成这个开关按钮的状态
                settingPopupWindow.setSwitchButtonAction(Config.openTimer);
                //将当前设置文字水印状态与否设置成这个开关按钮的状态
                settingPopupWindow.setSwitchButton2Action(Config.waterMaskText != null);

                settingPopupWindow.showAsDropDown(floatBar);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    /**
     * @description: 初始化MainActivity视图
     * @Return: void
     **/
    private void initView() {
        //获取菜单布局
        View menu = floatBar.getChildAt(1);
        //获取菜单中各个菜单项
        mUndoView   = menu.findViewById(R.id.btn_undo);
        mRedoView   = menu.findViewById(R.id.btn_redo);
        mPenView    = menu.findViewById(R.id.btn_pen);
        mEraserView = menu.findViewById(R.id.btn_eraser);
        mSaveView   = menu.findViewById(R.id.btn_save);
        mSetView    = menu.findViewById(R.id.btn_set);

        //写字板视图
        mPaintView = findViewById(R.id.paint_view);
        Log.e(TAG, "initView: mPaintView.toString() :" +mPaintView.toString()  );

        // TODO: 2021/11/19 这里可以使用监听，但是在floatBar中也设置了整体的监听,而且这里可以设置不同的对象，暂时留着
        /*mUndoView.setOnClickListener(this);
        mRedoView.setOnClickListener(floatBar);*/
        int mPenViewId = mPenView.getId();
        mPenView.setOnTouchListener(new MyClickListener(mPenViewId, this));
        int mEraserViewId = mEraserView.getId();
        mEraserView.setOnTouchListener(new MyClickListener(mEraserViewId, this));


        //选定视图是高亮显示的视图(开始时默认选择工具时pen，所以pen高亮，)
        mUndoView.setSelected(false);
        mRedoView.setSelected(false);
        mPenView.setSelected(true);
        mEraserView.setSelected(false);
        mSaveView.setSelected(false);

        mPaintView.setStepCallback(this);

        PenConfig.PAINT_SIZE_LEVEL  = PenConfig.getPaintTextLevel(this);
        PenConfig.PAINT_COLOR_LEVEL = PenConfig.getPaintColor(this);


    }

    /**
     * @description: 初始化数据
     * @Return: void
     **/
    private void initData() {

        // 因为现在的手机很多都是全面屏，并且基本上都是关闭了底部导航栏虚拟按键，所以一般方法获取的屏幕高度是不包含底部导航栏高度的，这里我们需要根据不同的手机设置不同的高度。
        paintHeight = mHeight;
        if (ScreenUtils.isAllScreenDevice(this) && ScreenUtils.checkHasNavigationBar(this)){
            //是是全面屏手机，并且关闭了底部导航栏，所以加上底部导航栏的宽度
            paintHeight = (int)mHeight + ScreenUtils.getNavigationBar(this);
            Log.e(TAG, "initSystem: ScreenUtils.isAllScreenDevice()  : "   +   ScreenUtils.isAllScreenDevice(this));
            Log.e(TAG, "initSystem: ScreenUtils.checkHasNavigationBar()  :"   +   ScreenUtils.checkHasNavigationBar(this));
            Log.e(TAG, "initSystem: maxHeight:"   +   paintHeight);
        }
        mPaintView.init(  (int) mWidth, (int)paintHeight, null);

        //真实的画布颜色，直接关系到图片的背景颜色。可通过设置Config.CANVAS_BG_COLOR来实现不同的背景
        bgColor = Config.Default_bg_Color;

        //如果传入了背景颜色那么就使用这个背景颜色作为这个画板的颜色 [这里必须要设置为与bgColor相同的颜色,mPaintView的颜色与绘制时所见到颜色直接相关，而bgColor与图片的真实背景相关，所有这两者必须一致]
        if (bgColor != Color.TRANSPARENT) {
            mPaintView.setBackgroundColor(bgColor);
        }


    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void onOperateStatusChanged() {
        mUndoView.setSelected(mPaintView.canUndo());
        mRedoView.setSelected(mPaintView.canRedo());
        mPenView.setSelected(!mPaintView.isEraser());
        mEraserView.setSelected(mPaintView.isEraser());
        mSaveView.setSelected(!mPaintView.isEmpty() && mPaintView.isHasNewAction());
    }

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case MSG_SAVE_FAILED:
                    //关闭此对话框，将其从屏幕上删除
                    mSaveProgressDlg.dismiss();
                    Toast.makeText(getApplicationContext(), "保存失败", Toast.LENGTH_SHORT).show();
                    break;
                case MSG_SAVE_SUCCESS:
                    mSaveProgressDlg.dismiss();
                    Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };

    /**
     * @description: 弹出设置页面
     * @Return: void
     **/
    private void showSettingWindow() {

        settingPopupWindow.setSettingListener(new SettingPopupWindow.OnClickSettingListener() {

            @Override
            public void onTimerSetting(boolean isOpen) {
                if (isOpen){
                    timer = new Timer();
                    TimerTask task = new TimerTask() {
                        @Override
                        public void run() {
                            //定时执行清屏任务
                            mPaintView.reset();
                        }
                    };
                    timer.schedule(task,0, Config.TIME_OF_CLEAR_SCREEN);
                }else {
                    timer.cancel();
                }

            }

            @Override
            public void onEraserWidthSetting(int width) {
                //修改Config.java中橡皮宽度，并且用于下一次打开设置弹出框中seekBar的值。
                Config.eraserSize = width;
                //清除原来的橡皮对象，并且创建一个新的橡皮对象，并且把这个新的橡皮对象传递出去
                mPaintView.newEraser(width);
            }

            @Override
            public void onImportPicSetting() {
                Intent intent = new Intent(Intent.ACTION_PICK, null);
                intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, 2);

            }

            @Override
            public void onBgColorSetting() {
                Log.e(TAG, "onBgColorSetting: 在MainActivity中收到"  );
            }

            @Override
            public void onShareSetting(boolean isShare) {
                Log.e(TAG, "onShareSetting: 在MainActivity中收到"  );
                if (!isShare || mPaintView.isEmpty()){
                    return;
                }else {
                    //进行保存
                    save();
                    //分享操作
                    Intent intent = new Intent(Intent.ACTION_SEND);
                    File f = new File(mSavePath);
                    if (f != null && f.exists() && f.isFile()) {
                        intent.setType("image/*");
                        //file:///storage/emulated/0/APenPipe/1637721552460GCZ.png   这种方式已过期，无法使用
                        //Uri u = Uri.fromFile(f);
                        //Log.e(TAG, "onShareSetting: Uri_u:" + u );

                        //content://com.threepure.penpipe.fileprovider/root_path/storage/emulated/0/APenPipe/1637721552460GCZ.png
                        Uri uriForFile = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".fileprovider", f);
                        Log.e(TAG, "onShareSetting: Uri_uriForFile:" +uriForFile );
                        intent.putExtra(Intent.EXTRA_STREAM, uriForFile);
                    }
                    intent.putExtra(Intent.EXTRA_SUBJECT, "管城子");
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(Intent.createChooser(intent, "Share to..."));
                }
            }

            @Override
            public void onTextMaskSetting(boolean isOpen) {
                if (isOpen){
                    final EditText name1 = new EditText(MainActivity.this);
                    AlertDialog.Builder isExit = new AlertDialog.Builder(MainActivity.this);
                    isExit.setTitle("最多显示10个汉字...");
                    isExit.setView(name1);
                    isExit.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Config.waterMaskText = name1.getText().toString();
                        }
                    });
                    isExit.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Config.waterMaskText = null;
                        }
                    });
                    isExit.setCancelable(false);
                    isExit.show();
                }else{
                    Config.waterMaskText = null;
                }

            }
        });

        View contentView = settingPopupWindow.getContentView();
        //需要先测量，PopupWindow还未弹出时，宽高为0
        contentView.measure(SystemUtil.makeDropDownMeasureSpec(settingPopupWindow.getWidth()),
                            SystemUtil.makeDropDownMeasureSpec(settingPopupWindow.getHeight()));
        SystemUtil.getScreenWidth(this);

        //根据悬浮按钮的位置，在悬浮菜单的上、下选择性的显示画笔设置弹出框.

        settingPopupWindow.popAtBottomRight();
        settingPopupWindow.showAsDropDown(floatBar, 5, 5);
    }

    /**
     * @description:  重写  用于接收获取的相册图片资源，并设置成背景
     * @Param: [int, int, android.content.Intent]
     * @Return: void
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == 2) {
            // 从相册返回的数据
            if (data != null) {
                // 得到图片的全路径
                Uri uri = data.getData();
                //保存这个uri，用于保存图片时使用
                Config.Default_bg_image = uri;
                Config.isImageBg = true;

                Bitmap bitmap = null;
                try {
                    bitmap = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(uri));
                    //缩放图片，使其铺满整个屏幕（图片长宽设置为手机屏幕长宽）
                    bitmap = BitmapUtil.zoomImage(bitmap, (int)mWidth, (int)paintHeight);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                Drawable drawable = new BitmapDrawable(bitmap);
                linearLayout.setBackground(drawable);
            }
        }

    }

    /**
     * @description:  弹出画笔设置
     * @Param: []
     * @Return: void
     */
    public void showPaintSettingWindow() {
        penSetPopWin.setSettingListener(new PenSettingPopupWindow.OnSettingListener() {
            @Override
            public void onSizeSetting(int index) {
                mPaintView.setPaintWidth(Config.PEN_SIZES[index]);
            }

            @Override
            public void onColorSetting(int index) {
                mPaintView.setPaintColor(Config.PEN_COLORS[index]);
            }
        });

        View contentView = penSetPopWin.getContentView();
        //需要先测量，PopupWindow还未弹出时，宽高为0
        contentView.measure(SystemUtil.makeDropDownMeasureSpec(penSetPopWin.getWidth()),
                            SystemUtil.makeDropDownMeasureSpec(penSetPopWin.getHeight()));
        SystemUtil.getScreenWidth(this);

        //根据悬浮按钮的位置，在悬浮菜单的上、下选择性的显示画笔设置弹出框.
        if (floatBar.getCurrentY() > mHeight * 2 / 3){
            penSetPopWin.popAtTopLeft();
            // TODO: 2021/11/22  使用了绝对定位，导致不同手机显示效果不同
            penSetPopWin.showAsDropDown(floatBar, 10, -(floatBar.getmLogoWidth() + penSetPopWin.getContentView().getMeasuredHeight() + 55 ));
        }else {
            penSetPopWin.popAtTopRight();
            penSetPopWin.showAsDropDown(floatBar, 10, 5);
        }

    }

    /**
     * @description: 保存到相册
     * @Return: void
     **/
    private void save() {
        if (mPaintView.isEmpty() || !mPaintView.isHasNewAction()) {
            return;
        }
        if (mSaveProgressDlg == null) {
            mSaveProgressDlg = new ProgressDialog(this);
            mSaveProgressDlg.setMessage("正在保存,请稍候...");
            //设置此对话框是否可使用后退键取消
            mSaveProgressDlg.setCancelable(false);
        }
        mSaveProgressDlg.show();

        Thread t = new Thread(() -> {
            try {

                Bitmap result = mPaintView.buildAreaBitmap(isCrop);
                //赋值format   解决没有给format赋值导致背景为透明，在相册中查看为全黑图片。
                format = "PNG";
                if (PenConfig.FORMAT_PNG.equals(format) && bgColor == Color.TRANSPARENT) {
                    bgColor = Color.WHITE;
                }

                if (!Config.isImageBg && bgColor != Color.TRANSPARENT ) {
                    //给Bitmap添加背景色 ，这个颜色与mPaintView.setBackgroundColor的颜色一直，
                    result = BitmapUtil.drawBgToBitmap(result, Config.Default_bg_Color);
                }

                //如果是使用的是图片背景，则把这个图片添加到这个Bitmap中。
                if (Config.isImageBg && Config.Default_bg_image != null){
                    //用户导入了自己的背景图片
                    Bitmap bitmap = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(Config.Default_bg_image));
                    result = BitmapUtil.addBgImage(result,bitmap);
                }else {
                    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.defaultbg);
                    result = BitmapUtil.addBgImage(result,bitmap);
                }

                if (Config.waterMaskText != null){
                    //用户自定义了水印文字
                    result = BitmapUtil.addTextWaterMask(result,Config.waterMaskText);
                }else {
                    //设置默认的图片水印
                    Bitmap watermark = BitmapFactory.decodeResource(getResources(),R.drawable.watermark);
                    watermark = BitmapUtil.zoomImg(watermark, 80);
                    result = BitmapUtil.addWaterMask(result, watermark, Color.TRANSPARENT, true);
                }

                if (result == null) {
                    mHandler.obtainMessage(MSG_SAVE_FAILED).sendToTarget();
                    return;
                }

                Log.e(TAG, "save: Config.isImageBg: " + Config.isImageBg );
                Log.e(TAG, "save: Config.Default_bg_image: " + Config.Default_bg_image );
                Log.e(TAG, "save: Config.Default_bg_Color: " + Config.Default_bg_Color );

                //保存图像到本地
                mSavePath = BitmapUtil.saveImage(MainActivity.this, result, 100, format);
                if (mSavePath != null) {
                    //更新画笔是否有新的动作
                    mPaintView.setHasNewAction(false);
                    //更新保存按钮的状态
                    mSaveView.setSelected(false);
                    Log.e(TAG, "save: " + mSavePath);
                    mHandler.obtainMessage(MSG_SAVE_SUCCESS).sendToTarget();
                } else {
                    mHandler.obtainMessage(MSG_SAVE_FAILED).sendToTarget();
                }
            } catch (Exception e) {
            }
        });
        t.start();
        try {
            //等待保存线程结束，以确保mSavePath正确
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    /**
     * @description: 一些系统初始化操作，比如获取
     * @Return: void
     **/
    private void initSystem(){

        //先检查是否有存储权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            //进行动态权限申请，（点击事件或主线程均可
            Log.e(TAG, "initSystem: 获取用户权限");
            ActivityCompat.requestPermissions(MainActivity.this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                         Manifest.permission.READ_EXTERNAL_STORAGE,
                                         Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS}, REQUEST_GPS);
            return;
        }

        //获取屏幕的真实尺寸：
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        mWidth  = dm.widthPixels;
        //这样获取的屏幕高度不正确（偏小），应该是减去了状态栏的高度
        mHeight = dm.heightPixels ;

        Log.e(TAG, "initSystem: mWidth  :"  +   dm.widthPixels);
        Log.e(TAG, "initSystem: mHeight :" +   dm.heightPixels);
    }

    @Override
    public void oneClick(int id) {
    }

    @Override
    public void doubleClick(int id) {
        if (id == mEraserView.getId()){
            //Log.e(TAG, "doubleClick => mEraserView.getId():" + mEraserView.getId() );
            mPaintView.reset();
        }else {
            return;
        }

    }

    /**
     * @description:  内部类，实现动态更换背景
     */
    public static class BackgroundColorListener implements ColorPickerDialog.OnColorChangedListener {
        public void onColorChanged(int color) {
            Config.Default_bg_Color = color;
            Config.isImageBg = false;
            linearLayout.setBackgroundColor(color);
        }
    }


}